package com.chen.springboot.common;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;

/**
 * @Author Chen
 * @Date 2024/11/2 11:43
 */
@WebFilter(urlPatterns = "/*")
public class LoginCheckFilter implements Filter {

    private static final String secretKey = "chen";

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        //1.获取请求url。
        String url = req.getRequestURL().toString();

        // 检查是否是白名单URL
        if (url.contains("login")||url.contains("files")||url.contains("manageLogin") ||
            url.contains("register")||url.contains("download")||url.contains("swagger")||
            url.contains("webjars")||url.contains("v2")||url.contains("address")||
            url.contains("itemOption")||url.contains("itemParams")||url.contains("ai")){
            chain.doFilter(request, response);
            return;
        }

        // 检查是否有@AuthAccess注解
        if (hasAuthAccessAnnotation(req)) {
            chain.doFilter(request, response);
            return;
        }

        //3.获取请求头中的令牌（token）。
        String jwt = req.getHeader("Authorization");
        // 验证 token 格式，如果为空，那么从url参数里面里面拿
        if (StrUtil.isBlank(jwt))
            jwt = request.getParameter("Authorization");

        //4.判断令牌是否存在，如果不存在，返回错误结果（未登录）。
        if (!StringUtils.hasLength(jwt)) {
            Result error = Result.error("401", "NOT_LOGIN");
            //手动转换 对象--json --------> 阿里巴巴fastJSON
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return;
        }

        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(secretKey)).build();

        //5.解析token，如果解析失败，返回错误结果（未登录）。
        try {
            jwtVerifier.verify(jwt);
        } catch (Exception e) {//jwt解析失败
            e.printStackTrace();
            Result error = Result.error("401", "NOT_LOGIN");
            //手动转换 对象--json --------> 阿里巴巴fastJSON
            String notLogin = JSONObject.toJSONString(error);
            resp.getWriter().write(notLogin);
            return;
        }

        //6.放行。
        chain.doFilter(request, response);

    }

    /**
     * 检查请求的方法是否有@AuthAccess注解
     */
    private boolean hasAuthAccessAnnotation(HttpServletRequest request) {
        try {
            // 获取请求路径
            String requestURI = request.getRequestURI();
            String method = request.getMethod();
            
            // 简单的注解检查逻辑
            // 这里可以根据实际需要扩展更复杂的注解检查逻辑
            if (requestURI.contains("/address/list")) {
                return true; // 临时允许地址列表接口
            }
            
            return false;
        } catch (Exception e) {
            return false;
        }
    }
}

